package org.example.java_gobang.api;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.example.java_gobang.game.MatchRequest;
import org.example.java_gobang.game.MatchResponse;
import org.example.java_gobang.game.Matcher;
import org.example.java_gobang.game.OnlineUserManager;
import org.example.java_gobang.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

//通过这个类来处理websocket请求
@Component
public class MatchAPI extends TextWebSocketHandler {
    private ObjectMapper objectMapper = new ObjectMapper();

    @Autowired
    private OnlineUserManager onlineUserManager;

    @Autowired
    private Matcher matcher;

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        // 玩家上线，加入到 OnlineUserManager 中
        // 1. 先获取到当前用户的身份信息 (谁在游戏大厅中，建立的连接)// 此处的代码，之所以能够 getAttributes，
        // 全靠了在注册 Websocket 的时候，
        // 加上的 .addInterceptors (new HttpSessionHandshakeInterceptor ());
        // 这个逻辑就把 HttpSession 中的 Attribute 都给拿到 WebSocketSession 中了
        // 在 Http 登录逻辑中，往 HttpSession 中存了 User 数据: httpSession.setAttribute ("user", user);
        // 此时就可以在 WebSocketSession 中把之前 HttpSession 里存的 User 对象给拿到了.
       try {
           User user = (User) session.getAttributes().get("user");
           //2.先查询这个id是否已经登录过了,如果已经登录了就不允许再登进去,没登过才可以登录

           if(onlineUserManager .getSessionFromGameHall(user.getUserId()) != null
                   || onlineUserManager.getSessionFromGameRoom(user.getUserId()) != null){
               //当前用户已经登录
               //要告诉客户端,不能重复登录
               MatchResponse response = new MatchResponse();
               response.setOk(true);
               response.setReason("当前禁止重复登录");
               response.setMessage("repeatConnection");
               session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
               //session.close();
               return;
           }

           //3.拿到身份后,就可以设置成在线状态了
           onlineUserManager.enterGameHall(user.getUserId(),session);
           System.out.println("玩家" + user.getUsername() + "进入游戏大厅");
       }catch (NullPointerException e){
           //出现空指针异常,说明当前登录信息为空
           //需要把当前用户未登录的信息返回回去
            e.printStackTrace();
            MatchResponse response = new MatchResponse();
            response.setOk(false);
            response.setReason("您尚未登录! 无法匹配!");

            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
       }

    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        // 1. 拿到⽤⼾信息.
        User user = (User) session.getAttributes().get("user");
        if (user == null) {
            System.out.println("[onMessage] 玩家尚未登录!");
            return;
        }
        System.out.println("开始匹配: " + user.getUsername() + " message: " + message.toString());
        // 2. 解析读到的数据为 json 对象
        String payload = message.getPayload();
        MatchRequest request = objectMapper.readValue(payload, MatchRequest.class);
        MatchResponse response = new MatchResponse();
        if ("startMatch".equals(request.getMessage()))
        {
            //进入匹配队列
            matcher.add(user);
            response.setOk(true);
            response.setMessage("startMatch");
        } else if ("stopMatch".equals(request.getMessage())) {
            //退出匹配队列
            matcher.remove(user);
            response.setOk(true);
            response.setMessage("stopMatch");
        } else {
            // 匹配失败
            response.setOk(false);
            response.setReason("⾮法的匹配请求!");
        }
        session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        try {
            //玩家下线,从onlineUserManager删除
            User user = (User) session.getAttributes().get("user");
            WebSocketSession tmpSession =  onlineUserManager.getSessionFromGameHall(user.getUserId());
            //WebSocketSession是当前的session,tmpSession是之前存好的,两个相等(即没有多开)才能正常删除,
            // 不然多开新的话会把之前的删了
            if(tmpSession == session){
                onlineUserManager.exitGameHall(user.getUserId());
            }
        }catch (NullPointerException e){
            //出现空指针异常,说明当前登录信息为空
            //需要把当前用户未登录的信息返回回去
            e.printStackTrace();
//            MatchResponse response = new MatchResponse();
//            response.setOk(false);
//            response.setReason("您尚未登录! 无法匹配!");
//
//            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
        }
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        try {
            //玩家下线,从onlineUserManager删除
            User user = (User) session.getAttributes().get("user");
            WebSocketSession tmpSession =  onlineUserManager.getSessionFromGameHall(user.getUserId());
            //WebSocketSession是当前的session,tmpSession是之前存好的,两个相等(即没有多开)才能正常删除,
            // 不然多开新的话会把之前的删了
            if(tmpSession == session){
                onlineUserManager.exitGameHall(user.getUserId());
            }
        }catch (NullPointerException e){
            //出现空指针异常,说明当前登录信息为空
            //需要把当前用户未登录的信息返回回去
            e.printStackTrace();
//            MatchResponse response = new MatchResponse();
//            response.setOk(false);
//            response.setReason("您尚未登录! 无法匹配!");
//
//            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
        }
    }
}
